package com.example.demo.common;

import java.util.HashSet;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.example.demo.domain.userInfo.UserInfo;

import com.example.demo.service.menu.MenuService;
import com.example.demo.service.role.RoleService;
import com.example.demo.service.userInfo.UserInfoService;


public class MyShiroRealm extends AuthorizingRealm {
	@Autowired
	UserInfoService userInfoService;
	@Autowired
	private MenuService menuService;

	@Autowired
	private RoleService roleService;

	/**
	 * 授权
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
		System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
		// SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		// UserInfo userInfo = (UserInfo) principal.getPrimaryPrincipal();
		// roleMapper(userInfo.getUsername()).stream().forEach(sysRole -> {
		// authorizationInfo.addRole(sysRole.getRole());
		// sysPermissionMapper.findPermissionByRoleId(sysRole.getId()).stream().forEach(sysPermission
		// -> {
		// authorizationInfo.addStringPermission(sysPermission.getPermission());
		// });
		// });
		// return authorizationInfo;
		UserInfo user = (UserInfo) principal.getPrimaryPrincipal();
		// 角色列表
		Set<String> roles = new HashSet<String>();
		// 功能列表
		Set<String> menus = new HashSet<String>();
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		// 管理员拥有所有权限
		if (user.isAdmin()) {
			info.addRole("admin");
			info.addStringPermission("*:*:*");
		} else {
			roles = roleService.selectRoleKeys(user.getUid());
			menus = menuService.selectPermsByUserId(user.getUid());
			// 角色加入AuthorizationInfo认证对象
			info.setRoles(roles);
			// 权限加入AuthorizationInfo认证对象
   		    info.setStringPermissions(menus);
		}
		return info;
	}

	/**
	 * 认证
	 */

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		System.out.println("MyShiroRealm.doGetAuthenticationInfo()");

		UsernamePasswordToken upToken = (UsernamePasswordToken) token;

		// 获得从表单传过来的用户名
		String username = upToken.getUsername();

		UserInfo userInfo = userInfoService.findByUsername(username);

		// 如果用户不存在，抛此异常
		if (userInfo == null) {
			throw new UnknownAccountException("无此用户名！");
		}

		// 认证的实体信息，可以是username，也可以是用户的实体类对象，这里用的用户名
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userInfo, // 用户名
				userInfo.getPassword(), // 密码
				ByteSource.Util.bytes(userInfo.getSalt()), // salt=username+salt
				this.getName() // realm name
		);
		return authenticationInfo;
	}

	/**
	 * 清理缓存权限
	 */
	public void clearCachedAuthorizationInfo() {
		this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
	}
}